<template>
  <div class="element-library-item-container" v-if="isFolder">
    <!--  外层容器  -->
    <div class="element-library-folder"
         :class="{'item-selected':isSelected}"
         :id="`element-library-item-${item.id}`"
         ref="itemElement"
         :style="{paddingLeft:`${layer * 8}px`}"
         :title="item.name"
         @click="clickEventHandler"
         @contextmenu="contextEventHandler"
         @dblclick="dbEventHandler">
      <!--   展开折叠的图标   -->
      <i class="font-weight: 900;padding: 0.5rem;"
         v-if="isFolder"
         :class="{'el-icon-arrow-right':collapse,'el-icon-arrow-down': !collapse}"
         @click.stop="collapseIconClickEventHandler"/>
      <div v-else class="collapse-placeholder"></div>
      <!--   Item的图标   -->
      <img v-if="isFolder"
           class="element-library-folder-icon"
           src="./images/file.svg"/>
      <img v-else class="item-icon" :src="item.thumbnail"/>
      <!--   Item的名称   -->
      <p v-if="!rename" class="element-library-folder-title">{{ item.name }}</p>
      <!--   创建新项目或重命名   -->
      <el-tooltip v-else
                  v-model="error"
                  :content="$t(errorTipContent)"
                  placement="bottom"
                  effect="light"
                  :manual="true">
        <input ref="create"
               @input="nameInputEventHandler"
               @blur.stop="inputBlurEventHandler"
               @keydown.enter.stop="inputBlurEventHandler"
               class="rename-input"
               :value.trim="item.name"/>
      </el-tooltip>

    </div>
    <!--  子项递归  -->
    <div v-show="!collapse" class="element-library-folder-children">
      <!--   循环递归子项   -->
      <template v-for="child in item.children">
        <ElementLibraryItem v-if="showVirtualNode(child.id)"
                       :selected-item="selectedItem"
                       :key="child.id"
                       :collapse-trigger="selfCollapseTrigger"
                       :item="child"
                       :layer="layer+1"/>
      </template>
    </div>
  </div>
</template>

<script>

  import {specialSymbol} from "./js/ElementLibraryRegx";
  import {LibraryItem, LibraryType} from "./js/ElementLibraryTypes";
  import {eventBus} from "../../../eventbus/eventbus";
  import {elementLibraryCmd} from "../../../Command/ElementLibrary/ElementLibraryCommand";
  import elementLibraryManager from "./js/ElementLibraryManager";

  export default {
    name: "ElementLibraryItem",
    inject: [
      "selectItemHandler",
      "rightClickItem",
      "openFolderEventHandler",
      "library",
      "cmd",
      "scrollElementLibraryContainer"
    ],
    props: {
      item: {
        type: LibraryItem,
        default: {
          name: ""
        }
      },
      layer: {
        type: Number,
        default: 0
      },
      collapseTrigger: {
        type: Boolean,
        default: false
      },
      selectedItem: Object
    },
    data() {
      return {
        collapse: true,
        selfCollapseTrigger: false,
        rename: false,
        oldName: "",
        errorTipContent: "message.ElementLibrary.fileNameErrorTip",
        error: false,
        enterPress: false,
        loadRecord: new Map(),
      }
    },
    mounted() {
      this.initEvent();
      // 该Id表示用户当前新建项
      if (this.item.id === "-1") {
        this.rename = true;
        this.oldName = this.item.name;
        this.enterPress = false;
        this.$nextTick(() => {
          this.focusCreateFolderInput();
        });
      }
    },
    methods: {
      // 在命令中不显示预创建的文件夹
      showVirtualNode(id) {
        return this.library || id !== "-1";
      },
      collapseIconClickEventHandler() {
        this.openOrCloseFolder();
      },
      /**
       *
       * @param e {InputEvent}
       */
      nameInputEventHandler(e) {
        if (!specialSymbol.test(e.data)) {
          this.item.name = e.target.value;
        } else {
          this.error = true;
          e.target.value = this.item.name;
          this.errorTipContent = this.$t('message.ElementLibrary.fileNameErrorTip');
        }
      },
      /**
       *
       * @param strValue 输入框输入的值，不能允许存在特殊字符
       * @param range 限制的字符长度
       * @return {boolean} true为超过限制  false为未超过限制
       */
      checkLimitStr(strValue, range = 128) {
        let reg = new RegExp(/[^\x00-\xff]/g);
        // 一个中文为两个字符，匹配中文将中文替换为*,获取输入字符串的字符长度
        let charLength = strValue.replace(reg, '**').length;
        return charLength > range;
      },
      inputBlurEventHandler() {
        if (this.enterPress || this.error) return;
        this.item.name = this.item.name.trim();
        if (!this.item.name) {
          this.error = true;
          this.errorTipContent = this.$t('message.ElementLibrary.unnamedValid');
          return;
        } else if(this.checkLimitStr(this.item.name)) {
          this.error = true;
          this.errorTipContent = this.$t('message.ElementLibrary.nameExceedLength');
          return;
        }
        this.rename = false;
        this.enterPress = true;
        // 如果是重命名状态
        if (this.item.id !== "-1") {
          // 名字没有发生变化
          if (this.oldName === this.item.name) return;
          let params = {
            cmdName: 'renameElementLibraryItem',
            id: this.item.id,
            folderCode: this.item.folderCode,
            name: this.item.name,
          }
          elementLibraryCmd.executeElementLibraryCommand(params, res => {
            if (res.status === 200 && res.data.code === 200) {
              eventBus.emit("alert", this.$t('message.ElementLibrary.renameSuccess'), {type: "success"});
              this.clickEventHandler();
              elementLibraryManager.renameItem(this.item.id, this.item.name);
            } else {
              // 存在同名文件
              // 该变量用于标识用户是否执行过模态框的交互按钮
              // TODO: 由于模态框存在BUG，现在需要用它标识，后期如果BUG修复可以将该变量移除
              eventBus.emit("confirm", this.$t('message.ElementLibrary.warning'), this.$t('message.KnowledgeBase.willAddNumber'), {
                type: "warning",
                confirmButtonText: this.$t('message.ElementLibrary.confirm'),
                cancelButtonText: this.$t('message.ElementLibrary.cancel'),
                confirmCallback: () => {
                  let parentItem = this.elementLibraryItemMap.get(this.item?.folderCode) ?? null;
                  let childrenList = parentItem?.children ?? this.elementLibraryItems;
                  let newName = this.generateNameByNo(this.item.name, childrenList.filter(child => child.id !== "-1").map(child => child.name));
                  if (this.oldName !== newName) {
                    let params = {
                      cmdName: 'renameElementLibraryItem',
                      id: this.item.id,
                      folderCode: this.item.folderCode,
                      name: newName,
                    }
                    elementLibraryCmd.executeElementLibraryCommand(params, res => {
                      if (res.status === 200 && res.data.code === 200) {
                        elementLibraryManager.renameItem(this.item.id, newName);
                        eventBus.emit("alert", this.$t('message.ElementLibrary.renameSuccess'), {type: "success"});
                      }
                    });
                  }
                  this.item.name = this.oldName;
                  this.oldName = "";
                },
                closeCallback: () => {
                  this.item.name = this.oldName;
                  this.oldName = "";
                }
              })
            }
          });
        } else {
          // 在新建文件夹的情况下，无论用户执行哪一个操作都会创建该文件夹，只是生成依据(名称)不同，该函数是为了提高代码复用
          const generateFolder = (name) => {
            let childrenList = elementLibraryManager.getParentByItem(this.item)?.children ?? elementLibraryManager.elementLibraryItems;
            let newName = elementLibraryManager.generateNameByNo(name, childrenList.filter(child => child.id !== "-1").map(child => child.name));
            elementLibraryManager.createFolder(newName, elementLibraryManager.curCreateItem.folderCode, cb => {
              elementLibraryManager.afterCreateFolder();
              this.selectedItem = null;
            });
          };
          // 如果是创建文件夹状态
          elementLibraryManager.createFolder(elementLibraryManager.curCreateItem.name, elementLibraryManager.curCreateItem.folderCode, cb => {
            // 创建成功后执行创建成功后的处理方法
            elementLibraryManager.afterCreateFolder();
            this.selectedItem = null;
          })
          //         .catch(() => {
          //   // 存在同名文件
          //   // 同重命名
          //   eventBus.emit("confirm", this.$t('message.ElementLibrary.warning'), this.$t('message.ElementLibrary.willAddNumber'), {
          //     type: "warning",
          //     confirmButtonText: this.$t('message.ElementLibrary.confirm'),
          //     cancelButtonText: this.$t('message.ElementLibrary.cancel'),
          //     confirmCallback: () => {
          //       generateFolder(item.name);
          //     },
          //     closeCallback: () => {
          //       generateFolder(this.oldName);
          //     }
          //   })
          // });
        }
      },
      focusCreateFolderInput() {
        // 聚焦
        this.$refs.create.focus();
      },
      initEvent() {
        eventBus.on("elementLibrarySyncSelectLib", (item) => {
          if (this.library) {
            this.scrollElementLibrary(item.id);
          }
        });
        eventBus.on("elementLibrarySyncSelectCmd", (item) => {
          if (this.cmd) {
            this.scrollElementLibrary(item.id);
          }
        });
        this.collapseId = eventBus.on("elementLibraryItemCollapse", (id, status) => {
          if (id === this.item.id) {
            this.collapse = status;
          }
        })
        this.renameId = eventBus.on("renameElementLibraryItem", (id) => {
          if (!this.library) return;
          if (id === this.item.id) {
            this.rename = true;
            // 记录旧的名称，以防止名称不变但仍然发送请求的问题
            this.oldName = this.item.name;
            this.enterPress = false;
            this.createdOrRenamed = true;
            this.$nextTick(() => {
              this.focusCreateFolderInput();
            });
          }
        });
        // 要素库展开文件夹通讯，仅供侧边栏使用
        this.openFolderId = eventBus.on("openElementLibraryFolder", (id) => {
          // 不在要素库容器内
          if (!this.library) return;
          if (id === this.item.id && this.collapse) {
            this.openOrCloseFolder();
          }
        });
        // // 无历史记录
        // this.openFolderNoHistoryId = eventBus.on("openFolderNoHistory", (id, status) => {
        //   // 不在要素库容器内
        //   if (!this.library) return;
        //   if (id === this.item.id) {
        //     this.openOrCloseFolder(status);
        //   }
        // });
        // 侧边栏展开文件夹
        this.unfoldFolderId = eventBus.on("unfoldElementLibraryFolder", (folderList, status, targetId) => {
          // 不在要素库容器内
          if (!this.library) return;
          if (folderList.includes(this.item.id) || targetId === this.item.id) {
            this.openOrCloseFolder(status);
          } else {
            this.openOrCloseFolder(false);
          }
          this.scrollElementLibrary(targetId);
        });
        // 命令中展开文件夹
        this.cmdUnfoldFolder = eventBus.on("cmdUnfoldElementLibraryFolder", (folderList, status, targetId) => {
          // 不在要素库容器内
          if (!this.cmd) return;
          if (folderList.includes(this.item.id)) {
            this.openOrCloseFolder(status);
          } else {
            this.openOrCloseFolder(false);
          }
          this.scrollElementLibrary(targetId);
        });
      },
      scrollElementLibrary(targetId) {
        if (targetId === this.item.id) {
          setTimeout(() => {
            this.scrollElementLibraryContainer(this.$refs.itemElement);
          }, 50);
        }
      },
      destroyEvent() {
        eventBus.off("elementLibrarySyncSelectLib", this.openFolderId);
        eventBus.off("elementLibrarySyncSelectCmd", this.openFolderId);
        eventBus.off("openElementLibraryFolder", this.openFolderId);
        eventBus.off("unfoldElementLibraryFolder", this.unfoldFolderId);
        eventBus.off("cmdUnfoldElementLibraryFolder", this.cmdUnfoldFolder);
        // eventBus.off("openFolderNoHistory", this.openFolderNoHistoryId);
        eventBus.off("renameElementLibraryItem", this.renameId);
        eventBus.off("elementLibraryItemCollapse", this.collapseId);
      },
      contextEventHandler(e) {
        this.clickEventHandler();
        this.rightClickItem?.(e);
      },
      dbEventHandler() {
        // 双击同时作用于这三个事件
        // openFolderEventHandler这个不一定存在
        // this.openFolderEventHandler?.(this.item.id);
        // this.openOrCloseFolder();
        // this.clickEventHandler();
        // if (elementLibraryManager.permitSync) {
        //   if (this.cmd) {
        //     eventBus.emit("openElementLibraryFolder", this.item.id);
        //   }
        //   elementLibraryManager.syncCmdAndRightNavigationSelected(this.item, this.cmd ? "cmd" : "library");
        // }
      },
      // 点击事件处理
      clickEventHandler() {
        //折叠/打开文件夹
        this.openOrCloseFolder();
        //加载子项
        this.openFolderEventHandler?.(this.item.id);
        if (this.cmd) {
          eventBus.emit("elementLibrarySyncSelectLib", this.item);
        } else if (elementLibraryManager.permitSync && !this.cmd) {
          // 如果两个面板同时处于激活状态,切换为同步模式
          eventBus.emit("elementLibrarySyncSelectCmd", this.item);
        }
        this.selectItemHandler?.(this.item);
      },
      // 展开或折叠文件夹
      openOrCloseFolder(status) {
        // 非文件夹不允许展开
        if (!this.isFolder) {
          return;
        }
        if (status !== undefined) {
          this.collapse = !status;
          return;
        }

        this.collapse = !this.collapse;
        if (this.collapse) {
          this.selfCollapseTrigger = true;
          setTimeout(() => {
            this.selfCollapseTrigger = false;
          });
        }
      },
    },
    computed: {
      isFolder() {
        return this.item.libraryType === LibraryType.FOLDER;
      },
      // 标识该项是否被
      isSelected() {
        // 如果选中的是注释
        return this.item.id === this.selectedItem?.id;
      }
    },
    beforeDestroy() {
      this.destroyEvent();
    },
    watch: {
      collapseTrigger: {
        handler(newVal) {
          if (newVal) {
            this.openOrCloseFolder(false);
          }
        }
      },
      error: {
        handler(val) {
          if (val === false) return;
          if (this.errorTimer) {
            clearTimeout(this.errorTimer);
          }
          this.errorTimer = setTimeout(() => {
            this.error = false;
          }, 1000)
        }
      },
      collapse: {
        handler(newVal) {
          // 在同步模式下，同步展开
          if (elementLibraryManager.permitSync) {
            eventBus.emit("elementLibraryItemCollapse", this.item.id, newVal);
          }
        }
      }
    }
  }
</script>

<style scoped>
  .item-selected {
    background-color: var(--bg-color8);
  }

  .element-library-folder {
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    height: 32px;
    -webkit-box-flex: 1;
    -webkit-flex: 110%;
    flex: 110%;
    cursor: pointer;
    -webkit-box-align: center;
    -webkit-align-items: center;
    align-items: center;
    padding-left: 0.25rem;
    padding-right: 0.25rem;
  }

  .element-library-folder-icon {
    height: 24px;
  }

  .element-library-folder-title {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    margin-left: 0.375rem;
  }

  .item-icon {
    @apply tw-w-[48px] tw-h-6 tw-bg-white;
  }

  .collapse-item {
    @apply tw-p-2;
  }

  .collapse-placeholder {
    @apply tw-w-[28px];
  }

  .rename-input {
    @apply tw-ml-1 tw-w-[80%];
  }
</style>